﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace thinger.VisionDemo
{
    public class TcpServer
    {
        private Socket listenerSocket;
        public Thread thread;
        public volatile bool ThreadControl;
        public Dictionary<string, Socket> L_connectedSocket = new Dictionary<string, Socket>();
        public event EventHandler<string> OnTCPSeverRecive;
        

        public bool isConnect()
        {
            if (L_connectedSocket.Count > 0)
            {
                foreach (KeyValuePair<string, Socket> kvp in L_connectedSocket)
                {
                    if (kvp.Key.IndexOf("3000") > -1)
                    {
                        return true;
                    }
                }
            }
            return false;
        }
        private static TcpServer instance;
        private static object instanceLock = new object();
        public static TcpServer Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (instanceLock)
                    {
                        if (instance == null)
                        {
                            instance = new TcpServer();
                        }
                    }
                }
                return instance;
            }
        }
        public TcpServer()
        {
        }
        public void Bing(int port = 3001)
        {
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, port);
            listenerSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            listenerSocket.Bind(endPoint);
            listenerSocket.Listen(10);
        }


        public void threadStart()
        {
            ThreadControl = true;
            thread = new Thread(new ThreadStart(AcceptClients));
            thread.IsBackground = true;
            thread.Start();
        }

        public void threadEnd()
        {
            ThreadControl = false;
            thread?.Abort();
            listenerSocket?.Close();
            listenerSocket?.Dispose();
            L_connectedSocket?.Clear();
        }
        public void AcceptClients()
        {
            try
            {
                while (ThreadControl)
                {
                    Socket clientSocket = listenerSocket.Accept();
                    if (!L_connectedSocket.ContainsKey(clientSocket.RemoteEndPoint.ToString()))
                    {
                        L_connectedSocket.Add(clientSocket.RemoteEndPoint.ToString(), clientSocket);
                        OnTCPSeverRecive?.Invoke(this, $"0,客户端：{clientSocket.RemoteEndPoint}连接！");
                    }

                    byte[] buffer = new byte[1024];
                    while (ThreadControl)
                    {
                        if (clientSocket.Poll(-1, SelectMode.SelectRead))
                        {
                            if (clientSocket.Available == 0)
                            {
                                if (L_connectedSocket.ContainsKey(clientSocket.RemoteEndPoint.ToString()))
                                {
                                    L_connectedSocket.Remove(clientSocket.RemoteEndPoint.ToString());
                                }
                                OnTCPSeverRecive?.Invoke(this, $"1,客户端：{clientSocket.RemoteEndPoint}断开连接！");
                                break;
                            }
                        }

                        int bytesRead = clientSocket.Receive(buffer);
                        if (bytesRead == 0) // Client disconnected
                        {
                            if (L_connectedSocket.ContainsKey(clientSocket.RemoteEndPoint.ToString()))
                            {
                                L_connectedSocket.Remove(clientSocket.RemoteEndPoint.ToString());
                            }
                            OnTCPSeverRecive?.Invoke(this, $"1,客户端：{clientSocket.RemoteEndPoint}断开连接！");
                            break;
                        }
                        else
                        {
                            string message = Encoding.Default.GetString(buffer, 0, bytesRead);
                            OnTCPSeverRecive?.Invoke(this, $"0,{message}");
                        }

                    }

                    clientSocket.Shutdown(SocketShutdown.Both);
                    clientSocket.Close();
                }
            }
            catch (Exception ex)
            {
                OnTCPSeverRecive?.Invoke(this, $"1,异常断开连接，错误信息: {ex}");
                threadEnd();
            }

        }

        public bool Send(string msg)
        {
            if (L_connectedSocket == null)
            {
                return false;
            }
            if (L_connectedSocket.TryGetValue("192.168.1.20:3000", out Socket Value))
            {
                Value.Send(Encoding.Default.GetBytes(msg));
                return true;
            }
            return false;
        }

    }
}
